﻿using System;
using System.Collections.Generic;
using System.ComponentModel.Design;
using System.IO;
using System.Linq;
using System.Runtime.Hosting;
using System.Text;
using System.Threading.Tasks;

namespace PythonInvokerTest.Utils
{
    /// <summary>
    /// 表示所执行的命令, 专用工具。
    /// </summary>
    public class ConsoleCommand
    {
        static char c20 = (char)20;
        static char c15 = (char)15;

        /// <summary>
        /// 脚本路径。
        /// </summary>
        public string ScriptPath { get; set; }
        public string Title { get; internal set; }

        /// <summary>
        /// 参数列表，格式为 a(15)b，其中a表示参数符，b表示参数值，并且第0个固定为输入，第1个固定为输出。
        /// </summary>
        public List<KeyValuePair> args = new List<KeyValuePair>();

        public ConsoleCommand()
        {
           Title = $"新脚本-{DateTime.Now:yyyy/MM/dd HH:mm:ss}";
        }

        /// <summary>
        /// 添加key-value对的参数。
        /// </summary>
        /// <param name="key">键。</param>
        /// <param name="argument">值。</param>
        public void AddArgument(string key, string argument)
        {
            args.Add(new KeyValuePair(key, argument));
        }

        public KeyValuePair this[int index]
        {
            get { return index >= 0 && index < args.Count ? args[index] : new KeyValuePair("", ""); }
        }

        /// <summary>
        /// 从字符串解析出一个ConsoleCommand对象，解析失败返回为null。
        /// </summary>
        /// <param name="script"></param>
        /// <returns></returns>
        public static ConsoleCommand FromString(string script)
        {
            var strs = (script + "").Trim().Split(c20);
            if (strs.Length == 0)
                return null;
            var cmd = new ConsoleCommand();
            var ss0 = strs[0].Split(new char[] { c15 }, StringSplitOptions.None);
            if (ss0.Length == 2)
            {
                cmd.ScriptPath = ss0[0];
                cmd.Title = ss0[1];
            }
            for (int i = 1; i < strs.Length; i++)
            {
                var ssi = strs[i].Split(new char[] { c15 }, StringSplitOptions.None);
                if (ssi.Length == 2)
                    cmd.AddArgument(ssi[0], ssi[1]);
            }
            return cmd;
        }

        /// <summary>
        /// 变为精简字符串，用于文件存在。格式为 path+[key][values]
        /// </summary>
        /// <returns></returns>
        public string ToFileString()
        {
            List<string> list = new List<string> { $"{ScriptPath}{c15}{Title}" };
            foreach (var arg in args)
                list.Add($"{arg.Key}{c15}{arg.Value}");
            return string.Join($"{c20}", list);
        }

        public override string ToString()
        {
            //StringBuilder sb = new StringBuilder();
            //sb.AppendLine($"脚本路径：{ScriptPath}");
            //foreach (var arg in args)
            //    sb.AppendLine($"参数i: {arg}".Replace((char)15, '='));
            //return sb.ToString();
            return this.Title;
        }

        /// <summary>
        /// 将当前对象的值写入目标文件路径。
        /// </summary>
        /// <param name="filepath">目标文件路径。</param>
        public void WriteFile(string filepath)
        {
            File.WriteAllText(filepath, ToFileString(), Encoding.UTF8);
        }

        /// <summary>
        /// 读取成功返回一个ConsoleCommand对象，否则返回null。
        /// </summary>
        /// <param name="filepath">待读取路径。</param>
        /// <returns></returns>
        public static ConsoleCommand ReadFile(string filepath)
        {
            return File.Exists(filepath) ? FromString(File.ReadAllText(filepath, Encoding.UTF8)) : null;
        }

        public void Copy(ConsoleCommand cmd1)
        {
            ScriptPath = cmd1.ScriptPath + "";
            Title = cmd1.Title + "";
            args = new List<KeyValuePair>();
            for (int i = 0; i < cmd1.args.Count; i++)
                args.Add(cmd1.args[i].Clone());
        }
    }

    public class KeyValuePair
    {
        public string Key { get; set; }
        public string Value { get; set; }
        public KeyValuePair(string key, string value)
        {
            Key = key;
            Value = value;
        }

        public override string ToString()
        {
            return $"{Key}: {Value}";
        }

        public KeyValuePair Clone()
        {
            return new KeyValuePair(Key + "", Value + "");
        }
    }
}
